// DisplayWnd.cpp: 实现文件
//

#include "stdafx.h"
#include "GUI.h"
#include "DisplayWnd.h"
#include "afxdialogex.h"


// DisplayWnd 对话框

IMPLEMENT_DYNAMIC(DisplayWnd, CDialogEx)

/*
DisplayWnd::DisplayWnd(Judge * j, CWnd* pParent , bool showVerbose)
	: CDialogEx(IDD_DIALOG1, pParent)
{
	pJudge = j;
	ver = showVerbose;
	fileVec.reserve(10000);
}
*/

DisplayWnd::DisplayWnd(JudgeProp prop, CWnd * pParent) 
	: CDialogEx(IDD_DIALOG1, pParent)
{
	pJudge = prop.JudgeClass;
	ver = prop.ShowVerbose;
	//ignoreFormat = (prop.Policy == Judge::IgnoreFormat);
	policy = prop.Policy;
	fileVec.reserve(prop.FileReserve);
	//isJudging = false;

	ResultDisplayBox.GetDefaultCharFormat(def);
	if (CFE_AUTOCOLOR & def.dwEffects)
	{
		def.dwMask = CFM_ALL2;
		def.wKerning = 100;
		def.dwEffects -= CFE_AUTOCOLOR;
		def.crBackColor = RGB(255, 255, 255);
		def.crTextColor = RGB(0, 0, 0);
		wcscpy_s(def.szFaceName, _T("宋体"));
		ResultDisplayBox.SetDefaultCharFormat(def);
	}

	title = def;
	error = def;
	wrnig = def;
	accpt = def;
	verbo = def;
	error_crit = def;

	title.dwEffects = CFE_BOLD;
	error.crTextColor = RGB(255, 0, 0);
	wrnig.crTextColor = RGB(0, 0, 255);
	accpt.crTextColor = RGB(0, 255, 0);
	verbo.crTextColor = RGB(127, 127, 127);
	error_crit.dwEffects = CFE_BOLD;
	error_crit.crTextColor = RGB(255, 0, 0);

}

DisplayWnd::~DisplayWnd()
{
	fileVec.clear();
}

void DisplayWnd::DoDataExchange(CDataExchange* pDX)
{
	CDialogEx::DoDataExchange(pDX);
	DDX_Control(pDX, IDC_RICHEDIT22, ResultDisplayBox);
	DDX_Control(pDX, IDC_PROGRESS, ResProgress);
}


BEGIN_MESSAGE_MAP(DisplayWnd, CDialogEx)
	ON_BN_CLICKED(IDC_BUTTON_START, &DisplayWnd::OnBnClickedButtonStart)
	ON_BN_CLICKED(IDOK, &DisplayWnd::OnBnClickedOk)
	ON_BN_CLICKED(IDC_DETAIL, &DisplayWnd::OnBnClickedDetail)
END_MESSAGE_MAP()


// DisplayWnd 消息处理程序


void DisplayWnd::OnBnClickedButtonStart()
{
	ResultDisplayBox.Clear();
	wchar_t content[1024];

	FILE *olog;
	_wfopen_s(&olog, TEXT("Judge_result.log"), TEXT("w"));
	
	this->Append(_T("开始评测："), title);
	this->Append(pJudge->user_program, title);
	this->Append(_T("\n"), title);

	if(ver)
		this->Append(_T("正在初始化环境...\n"), verbo);
	pJudge->InitTestEnvironment();

	if (ver)
	{
		this->Append(_T("正在生成测试点...\n"), verbo);
		this->Append(pJudge->input_data_form, verbo);
		this->Append(_T("\n"), verbo);
		this->Append(pJudge->output_data_form, verbo);
		this->Append(_T("\n"), verbo);
	}

	fileVec.clear();
	pJudge->GetDataList(fileVec);

	if(ver)
		this->Append(_T("测试点生成完成！\n"), verbo);

	if (fileVec.empty())
		this->Append(_T("没有找到测试数据\n"), wrnig);
	
	if (!pJudge->pSetter->IsExist(pJudge->user_program))
	{
		this->Append(_T("\t未找到源文件\n"), error);
		return;
	}
	size_t errcode = 0LL, totalData = fileVec.size();

	wsprintf(content, _T("总计%d组测试数据\n"), totalData);
	this->Append(content, verbo);

	ResProgress.SetRange32(0, totalData);

	TINFO res;
	this->Append(_T("测试时请保持计算机空闲\n"), wrnig);
	for (auto itr = fileVec.begin(); itr != fileVec.end(); itr++)
	{
		wsprintf(content, _T("\t测试点%d(%s %s)："), itr - fileVec.begin()+1, itr->in_data, itr->out_data);
		this->Append(content, def);
		errcode = pJudge->RunTest(itr->in_data, itr->out_data, &res, policy);

		if (errcode != TEST_SUCCESS && errcode != 0)
		{
			this->Append(_T("评测器已崩溃\n"), error_crit);
			wsprintf(content, _T("\t错误码：%d\n"), errcode);
			this->Append(content, error_crit);
			return;
		}

		switch (res.tResult)
		{
		case TINFO::ACCEPT:
			this->Append(_T("已通过\n"), accpt);
			break;
		case TINFO::WRONG_ANSWER:
			this->Append(_T("答案错误\n"), error);
			break;
		case TINFO::TIME_LIMIT_EXCEED:
			this->Append(_T("时间超限\n"), error);
			break;
		case TINFO::MEMORY_LIMIT_EXCEED:
			this->Append(_T("内存超限\n"), error);
			break;
		case TINFO::RUNTIME_ERROR:
			this->Append(_T("运行错误\n"), error);
			wsprintf(content, _T("\t\t返回码：0x%X\n"), res.retCode);
			this->Append(content, wrnig);
			break;
		case TINFO::CANT_OPEN_FILE:
			this->Append(_T("无法打开文件\n"), error_crit);
			break;
		default:
			this->Append(_T("未知错误\n"), error);
		}

		fwprintf(olog, TEXT("%s"), res.log);

		ResProgress.SetPos(itr - fileVec.begin() + 1);

		// 派发消息，防止主窗口卡死

		MSG & msg;
		if(PeekMessage(&msg,(HWND)NULL, 0, 0, PM_REMOVE))
			SendMessage(msg.hwnd, msg.message, msg.wParam, msg.lParam);

	}

	fclose(olog);
	
	pJudge->CloseTest();
}

void DisplayWnd::Append(LPCTSTR str, CHARFORMAT2W format)
{
	ResultDisplayBox.SetSel(-1, -1);
	ResultDisplayBox.SetSelectionCharFormat(format);
	ResultDisplayBox.ReplaceSel(str);
	this->UpdateWindow();
}


void DisplayWnd::OnBnClickedOk()
{
	// TODO: 在此添加控件通知处理程序代码
	CDialogEx::OnOK();
}


void DisplayWnd::OnBnClickedDetail()
{
	char cmd2[MAX_PATH * 2];
	wchar_t cmd[MAX_PATH * 2] = TEXT("notepad \"");
	wcscat_s(cmd, pJudge->path);
	wcscat_s(cmd, TEXT("Judge_result.log\""));

	int len = WideCharToMultiByte(CP_ACP, 0, cmd, wcslen(cmd), NULL, 0, NULL, NULL);
	WideCharToMultiByte(CP_ACP, 0, cmd, wcslen(cmd), cmd2, len, NULL, NULL);
	cmd2[len] = '\0';

	WinExec(cmd2, SW_SHOW);

	// TODO: 在此添加控件通知处理程序代码
}
